package com.trust.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.trust.agri.exception.ServiceException;
import com.trust.agri.util.BeanUtil;
import com.trust.constant.Constants;
import com.trust.constant.InventoryTypeEnum;
import com.trust.entity.*;
import com.trust.entity.DTO.FarmSeedDTO;
import com.trust.entity.Param.FarmSeedListParam;
import com.trust.entity.VO.DictionaryVO;
import com.trust.entity.VO.FarmSeedListVO;
import com.trust.entity.VO.FarmSeedVO;
import com.trust.entity.VO.PlantDropDown;
import com.trust.entity.result.DropDownResult;
import com.trust.mapper.FarmSeedMapper;
import com.trust.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class FarmSeedServiceImpl extends ServiceImpl<FarmSeedMapper, FarmSeed> implements FarmSeedService {


    @Resource
    private MedicineService medicineService;

    @Resource
    private SystemPersonService systemPersonService;

    @Resource
    private BreedService breedService;

    @Resource
    private SetupLandService setupLandService;

    @Resource
    private FarmPlantService farmPlantService;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private FarmSeedConsumableService farmSeedConsumableService;

    @Resource
    private FarmSeedLandService farmSeedLandService;

    @Resource
    private PurchaseService purchaseService;

    @Resource
    private InventoryMaterialService inventoryMaterialService;

    @Resource
    private InventoryRecordService inventoryRecordService;

    @Resource
    private SystemDepartmentService systemDepartmentService;

    @Override
    public Page<FarmSeedListVO> list(FarmSeedListParam param) {
        LambdaQueryWrapper<FarmSeed> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(param.getCode())) {
            wrapper.like(FarmSeed::getCode, param.getCode());
        }
        wrapper.eq(null != param.getCategoryId(), FarmSeed::getCategoryId, param.getCategoryId());
        wrapper.orderByDesc(FarmSeed::getId);
        Page<FarmSeed> page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
        Page<FarmSeedListVO> targetPage = BeanUtil.sourcePage2targetPage(page, FarmSeedListVO.class);
        for (FarmSeedListVO record : targetPage.getRecords()) {
            record.setPrincipalName(null == record.getPrincipal() ? null : systemPersonService.getNameById(record.getPrincipal()));
            //种植品类
            record.setCategoryName(medicineService.getNameById(record.getCategoryId()));
            //种源信息
            record.setBreedName(breedService.getNameById(record.getBreedId()));
            //种源批号
//            record.setBreedCodeName(inventoryMaterialService.getById(record.getBreedCode()).getCode());
            //作业地块
//            List<Integer> integers = JSON.parseArray(record.getLandId(), Integer.class);
//            List<String> landCodes = new ArrayList<>();
//            for (Integer integer : integers) {
//                landCodes.add(setupLandService.getCodeById(integer));
//            }
//            record.setLandCode(landCodes);
        }
        return targetPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FarmSeed saveAndUpdate(FarmSeedDTO param) {
        FarmSeed target = BeanUtil.source2target(param, new FarmSeed());

        if (ObjectUtil.isNotEmpty(target)) {
            if (null != param.getId() && !param.getId().equals(target.getId())) {
                throw new ServiceException("育苗批号重复！");
            }
        }
        //List<FarmPlantLand> farmPlantLands = farmPlantLandService.getByLandIds(param.getLandId());
        //if (CollectionUtil.isNotEmpty(farmPlantLands)){
        //    throw new ServiceException("地块已有种植任务，请勿重复添加");
        //}
        //List<FarmSeedLand> farmSeedLands = farmSeedLandService.getByLandIds(param.getLandId());
        //if (CollectionUtil.isNotEmpty(farmSeedLands)){
        //    if (farmSeedLands.size() > 1){
        //        throw new ServiceException("地块已有育苗任务，请勿重复添加");
        //    }
        //    if (null == param.getId() || !param.getId().equals(farmSeedLands.get(0).getFarmSeedId())){
        //        throw new ServiceException("地块已有育苗任务，请勿重复添加");
        //    }
        //}
        try {
            for (Integer landId : param.getLandId()) {
                SetupLand land = setupLandService.getById(landId);
                if (land.getPlantType() != null && land.getPlantType() == 1) {
                    FarmPlant farmPlant = farmPlantService.getById(land.getCurrentPlantId());
                    Assert.isTrue(farmPlant == null || farmPlant.getState() == 2, "该地块已有种植任务，请勿重复添加");
                }
                if (land.getPlantType() != null && land.getPlantType() == 2 && param.getId()==null) {
                    FarmSeed farmSeed = this.getById(land.getCurrentPlantId());
                    Assert.isTrue(farmSeed == null || farmSeed.getState() == 2, "该地块已有育苗任务，请勿重复添加");
                }
            }
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }

        target.setLandId(JSON.toJSONString(param.getLandId()));
        target.setState(1);

        // 设置 materials 字段
        target.setMaterials(param.getMaterials());

        //辅助育苗设施
        if (CollectionUtil.isNotEmpty(param.getSeedFacilityList())) {
            for (DictionaryVO dictionaryVO : param.getSeedFacilityList()) {
                if (null == dictionaryVO.getId()) {
                    dictionaryVO.setId(dictionaryService.save(74, dictionaryVO.getName()));
                }
            }
            target.setSeedFacility(JSON.toJSONString(param.getSeedFacilityList()));
        }
       /* if (null == param.getSeedFacilityId() && StringUtils.isNotBlank(param.getSeedFacilityName())){
            target.setSeedFacilityId(dictionaryService.save(74, param.getSeedFacilityName()));
        }*/
        //育苗方式
        if (null == param.getType() && StringUtils.isNotBlank(param.getTypeName())) {
            target.setType(dictionaryService.save(94, param.getTypeName()));
        }
        this.saveOrUpdate(target);
        if (null != param.getId()) {
            farmSeedConsumableService.removeByFarmSeedId(param.getId());
            farmSeedLandService.removeByFarmSeedId(param.getId());
        }
        for (Integer integer : param.getLandId()) {
            FarmSeedLand farmSeedLand = new FarmSeedLand(target.getId(), integer);
            farmSeedLandService.save(farmSeedLand);
        }

        for (Integer integer : param.getLandId()) {
            SetupLand land = setupLandService.getById(integer);
            land.setPlantCateId(param.getBreedId());
            land.setColor(param.getColor());
            land.setCurrentPlantId(target.getId());
            land.setCurrentPlantCode(param.getCode());
            land.setPlantType(2);
            //land.setStartTime(param.getPlantStart());
            setupLandService.updateById(land);
        }

        //出库
        String inCode = purchaseService.generalInCode();
        if (null == param.getId()) {
            //库存
            InventoryMaterial material = inventoryMaterialService.getById(param.getBreedCode());
            if(param.getBreedNum().compareTo(material.getStock()) > 0){
                throw  new ServiceException("种源库存不足");
            }
            BigDecimal subtract = material.getStock().subtract(param.getBreedNum());
            material.setStock(subtract);
            inventoryMaterialService.updateById(material);

            //出入库记录
            InventoryRecord record = new InventoryRecord();
            record.setLinkCode(target.getCode());
            record.setStockCode(param.getBreedCodeName());
            record.setCode("C" + inCode);
            record.setUnitId(material.getUnitId());
            record.setUnit(material.getUnit());
            record.setMaterialId(material.getMaterialId());
            record.setMaterialName(material.getMaterialName());
            record.setStorehouseId(material.getStorehouseId());
            record.setInventoryTime(new Date());
            record.setNum(BigDecimal.valueOf(param.getSeedNum()));
            record.setMaterialType(-1);
            record.setMaterialTypeName("种子");
            record.setInventoryType(Constants.SEED_OUT);
            record.setMaterialCode(material.getCode());
            record.setParentId(target.getId());
            inventoryRecordService.save(record);
        } else {
            InventoryRecord inventoryRecord = inventoryRecordService.getByTypeAndParentId(InventoryTypeEnum.SEED_OUT.getId(), param.getId());
            //库存
            InventoryMaterial material = inventoryMaterialService.getById(param.getBreedCode());
            material.setStock(material.getStock().subtract(BigDecimal.valueOf(param.getSeedNum())).add(inventoryRecord.getNum()));
            inventoryMaterialService.updateById(material);

            //出入库记录
            inventoryRecordService.removeByParentId(param.getId());
            InventoryRecord record = new InventoryRecord();
            record.setLinkCode(target.getCode());
            record.setStockCode(param.getBreedCodeName());
            record.setCode("C" + inCode);
            record.setUnitId(material.getUnitId());
            record.setUnit(material.getUnit());
            record.setMaterialId(material.getMaterialId());
            record.setMaterialName(material.getMaterialName());
            record.setStorehouseId(material.getStorehouseId());
            record.setInventoryTime(new Date());
            record.setNum(BigDecimal.valueOf(param.getSeedNum()));
            record.setMaterialType(-1);
            record.setMaterialTypeName("种子");
            record.setInventoryType(Constants.SEED_OUT);
            record.setMaterialCode(material.getCode());
            record.setParentId(param.getId());
            inventoryRecordService.save(record);
        }
        return target;
    }



    @Override
    public List<DropDownResult> breed(Integer medicineId) {
        LambdaQueryWrapper<InventoryMaterial> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InventoryMaterial::getMaterialId, medicineId)
                .eq(InventoryMaterial::getType, -1)
                .gt(InventoryMaterial::getStock, 0)
                .eq(InventoryMaterial::getReleaseState, 2)
                .orderByDesc(InventoryMaterial::getId);
        List<InventoryMaterial> list = inventoryMaterialService.list(wrapper);
        List<DropDownResult> results = new ArrayList<>();
        for (InventoryMaterial material : list) {
            DropDownResult drop = new DropDownResult();
            drop.setId(material.getId());
            drop.setName(material.getCode());
            results.add(drop);
        }
        return results;
    }

    @Override
    public FarmSeedVO info(Integer id) {
        FarmSeed farmSeed = this.getById(id);
        FarmSeedVO target = BeanUtil.source2target(farmSeed, new FarmSeedVO());
        //种植品类
        target.setCategoryName(medicineService.getNameById(target.getCategoryId()));
        //辅助育苗设施
        target.setSeedFacilityList(JSONArray.parseArray(farmSeed.getSeedFacility(), DictionaryVO.class));
        //target.setSeedFacilityName(null == target.getSeedFacilityId() ? null : dictionaryService.getNameById(target.getSeedFacilityId()));
        //种源信息
        target.setBreedName(breedService.getNameById(target.getBreedId()));
        //种源批号
        InventoryMaterial material = inventoryMaterialService.getById(target.getBreedCode());
        target.setBreedCodeName(material.getCode() + material.getMaterialName());
        //作业班组
        target.setWorkGroupName(systemDepartmentService.getNameById(target.getWorkGroupId()));
        //负责人
        target.setPrincipalName(null == target.getPrincipal() ? null : systemPersonService.getNameById(target.getPrincipal()));
        //育苗方式
        target.setTypeName(null == target.getType() ? null : dictionaryService.getNameById(target.getType()));
        //作业地块
        List<Integer> integers = JSON.parseArray(farmSeed.getLandId(), Integer.class);
        List<DictionaryVO> landCodes = new ArrayList<>();
        for (Integer integer : integers) {
            landCodes.add(new DictionaryVO(integer, setupLandService.getCodeById(integer)));
            SetupLand setupLand = setupLandService.getById(integer);
            if (ObjectUtil.isNotEmpty(setupLand)) {
                target.setColor(setupLand.getColor());
            }
        }
        target.setLandId(integers);
        target.setLandObj(landCodes);
        //作业耗材
        List<FarmSeedConsumable> consumableList = farmSeedConsumableService.getByFarmSeedId(id);
        target.setConsumableList(consumableList);
        return target;
    }

    @Override
    public List<DropDownResult> dropDown() {
        LambdaQueryWrapper<FarmSeed> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FarmSeed::getState, 1)
                .orderByDesc(FarmSeed::getId);
        List<FarmSeed> list = this.list(wrapper);
        List<DropDownResult> results = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(list)) {
            for (FarmSeed farmSeed : list) {
                DropDownResult drop = new DropDownResult(farmSeed.getId(), farmSeed.getCode());
                results.add(drop);
            }
        }
        return results;
    }

    @Override
    public List<PlantDropDown> dropDownList() {
        LambdaQueryWrapper<FarmSeed> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FarmSeed::getState, 1);
        List<FarmSeed> list = this.list(wrapper);
        List<PlantDropDown> dropDownList = new ArrayList<>();
        for (FarmSeed farmSeed : list) {
            PlantDropDown drop = new PlantDropDown();
            drop.setId(farmSeed.getId());
            drop.setPlantCode(farmSeed.getCode());
            List<Integer> integers = JSON.parseArray(farmSeed.getLandId(), Integer.class);
            List<DictionaryVO> lands = new ArrayList<>();
            for (Integer integer : integers) {
                DictionaryVO vo = new DictionaryVO();
                vo.setId(integer);
                vo.setName(setupLandService.getCodeById(integer));
                lands.add(vo);
            }
            drop.setLands(lands);
            drop.setName(farmSeed.getCode());
            dropDownList.add(drop);
        }
        return dropDownList;
    }

    @Override
    public String getCateNameById(Integer id) {
        FarmSeed seed = this.getById(id);
        if (null == seed) {
            return "";
        }
        return breedService.getNameById(seed.getBreedId());
    }
}
